#! /usr/bin/env python2

import cv2
import cv 
import numpy as np

state = 0
state2 = 0
whiteboard = 0
command = -1
#s_img = cv2.imread("small_marker.png", 3)
s_img = cv2.imread("marker.png", 3)
s_img2 = cv2.imread("erasor.png", 3)
s_img3 = cv2.imread("arrow.png", 3)
SCREENSIZE = [1024,768]

DRAW = cv.CreateImage(SCREENSIZE, cv.IPL_DEPTH_8U, 3)


class GestureTracker: 

	def __init__(self):
		gesture_window = "Gesture Tracker"            		
		cv2.namedWindow(gesture_window)
		self.camera = cv2.VideoCapture(1)

	def run(self):

		if self.camera.isOpened():
			rval, frame = self.camera.read()
		else:
			rval = False

		while rval:
		 	rval,frame = self.camera.read()
		 	frame,draw,command,topmost,whiteboard, thresh2 = self.gestures(frame, DRAW)

		 	print "COMMAND IS:" 
		 	print  command
		 	cv2.imshow('thresh', thresh2)
			cv2.imshow('gesture_window', frame)

			key = cv2.waitKey(1)
			if key == 27:
				cv2.destroyAllWindows()
				self.camera.release()
				break

	def gestures(self, frame, draw):
			# smoothen the picture 
			frame = cv2.blur(frame,(3,3))
			hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
			thresh = cv2.inRange(hsv,np.array((70, 40, 40)), np.array((125, 255, 255)))
			thresh2 = thresh.copy()
			contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
			max_area = 1300
			num_defects = -1
			num_pointers = 0
			click = 0
			topmost = [0,0]
			global state
			global state2
			global whiteboard
			global command
			command = -1

			for cnt in contours:
				#print "inside contours"
				area = cv2.contourArea(cnt)
				if area > max_area:
					#print "inside area"
					max_area = area
					best_cnt = cnt
					x,y,w,h = cv2.boundingRect(best_cnt)
					aspect_ratio = float(w)/h

			if(max_area > 1300 and aspect_ratio >.3 and aspect_ratio < 1.6):
				print "aspect_ratio is:"
				print aspect_ratio
				command = 0
				#print len(contours)
				#print 'area is: ' + str(max_area)
				#cv2.drawContours(frame,[best_cnt],0,(255,0,0),3)
				hull = cv2.convexHull(best_cnt)
				cv2.drawContours(frame,[hull],0,(0,255,0),2)
				hull_2 = cv2.convexHull(best_cnt,returnPoints = False)
				defects = cv2.convexityDefects(best_cnt,hull_2)
				if defects != None:
					num_defects = 0
					defect_array = []
					for i in range(defects.shape[0]):
						s,e,f,d = defects[i,0]
						#print 'number of defects are:' + str(defects.shape[0])
						start = tuple(best_cnt[s][0])
						end = tuple(best_cnt[e][0])
						far = tuple(best_cnt[f][0])

						if d > 6000 and d < 15000:	
							# print 'start is: ' + str(start)
 						# 	print 'end is: ' + str(end)
							# print 'far is: ' + str(far)
							# print 'depth is:' + str(d)
							cv2.circle(frame,start,4,[255,0,0],-1)
							cv2.circle(frame,end,4,[255,0,0],-1)
							cv2.circle(frame,far,4,[0,0,255],-1)
							triple = [start,end,far]
							defect_array.append(triple)
							num_defects+=1


			textColor = (22, 22, 22)

			if whiteboard == 2:

				if num_defects == 0:
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					cv2.putText(frame, "Eraser", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					if state == 1:
						state = 2
					if state == 2:
						cv2.circle(draw,(topmost[0],topmost[1] - 30),2000,(0,0,0),-1)
						state = 0
					if state2 == 1:
						state2 = 2
					if state2 == 2:
						cv2.circle(draw,(topmost[0],topmost[1] - 30),2000,(0,0,0),-1)
						whiteboard = 0


				if num_defects == 1 or num_defects == 2: 
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					state = 0
					state2 = 0
					#if defect_array[0][0][1] 
					cv2.putText(frame, "Pointer ", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					#topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					cv2.circle(draw,(topmost[0],topmost[1]),10,(12,122,34),-1)
					global s_img
					try:
						if(topmost[1]>=0 and topmost[0]>=0 and
							(topmost[1]+ s_img.shape[0]) >= s_img.shape[0] and 
							(topmost[0]+ s_img.shape[1]) >= s_img.shape[1]):
							frame[topmost[1]:topmost[1]+s_img.shape[0], topmost[0]:topmost[0] +s_img.shape[1]] = s_img
			
					except:
						return frame,draw,command,topmost,whiteboard
				#if num_defects == 2: 
				#	cv2.putText(frame, "Chill", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)

				#if num_defects == 3: 
				#cv2.putText(frame, "Tao: bla bla bla", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)

				if num_defects >=3 and num_defects <=6: 
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					state = 1
					if(num_defects == 3):
						state2 = 1
					cv2.putText(frame, "Eraser", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					#topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					rightmost = tuple(best_cnt[best_cnt[:,:,0].argmax()][0])
					global s_img2
					try: 
						if((topmost[1] -40 >=0) and (topmost[0] -50 >=0) and 
							(topmost[1]-40+s_img2.shape[0]) >= s_img2.shape[0] and
							(topmost[0]-50 + s_img2.shape[1]) >= s_img2.shape[1]):
							frame[topmost[1]-40:topmost[1]-40+s_img2.shape[0], topmost[0]-50:topmost[0]-50 + s_img2.shape[1]] = s_img2
							cv2.rectangle(draw, (topmost[0] -50 ,topmost[1] -40), (topmost[0]-50 + s_img2.shape[1],topmost[1] -40 + s_img2.shape[0]), (0,0,0), -1)
					except:
						return frame,draw,command,topmost,whiteboard
					#cv2.rectangle(frame, (topmost[1] -40 ,topmost[0] -50), (topmost[1]-40 + s_img2.shape[0],topmost[0] -50 + s_img2.shape[1]), (255,0,0), -1)


				#if num_defects == 1 & num_pointers == 1:
			
			if whiteboard == 0:
				if num_defects == 1: 
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					#cv2.putText(frame, "click", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					command = 3

				if num_defects == 0:
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					cv2.putText(frame, "Eraser", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					command = 0
					state2 = 1
					if state == 1:
						state = 2
					if state == 3:
						command = 5
						state = 0
					
				if num_defects >=3 and num_defects <=8: 
					if state == 0:
						state = 1

					if state == 2:
						state = 3
					#if(state2 ==1):
					#	command = 4
					#	state2 = 0

				if num_defects == -45:
					topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					command = 0 
					#state = 0
					#if defect_array[0][0][1] 
					cv2.putText(frame, "Pointer ", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
					#cv2.circle(draw,(topmost[0],topmost[1]),10,(12,122,34),-1)
					global s_img3
					try: 
						if(topmost[1]>=0 and topmost[0]>=0 and
							(topmost[1]+s_img3.shape[0]) >= s_img3.shape[0] and 
							(topmost[0]+ s_img3.shape[1]) >= s_img3.shape[1]):
							frame[topmost[1]:topmost[1]+s_img3.shape[0], topmost[0]:topmost[0] +s_img3.shape[1]] = s_img3
					except:
						return frame,draw,command,topmost,whiteboard


				#if num_defects == 2: 
				#if num_defects >=3 and num_defects <=3: 
				#	whiteboard = 0
				#	cv2.putText(frame, "Whiteboard", (150, 200),cv2.FONT_HERSHEY_PLAIN, 3.0, textColor,thickness=4)
				#	topmost = tuple(best_cnt[best_cnt[:,:,1].argmin()][0])
					#rightmost = tuple(best_cnt[best_cnt[:,:,0].argmax()][0])
					#global s_img2
					#frame[topmost[1]-40:topmost[1]-40+s_img2.shape[0], topmost[0]-50:topmost[0]-50 + s_img2.shape[1]] = s_img2
					#cv2.rectangle(draw, (topmost[0] -50 ,topmost[1] -40), (topmost[0]-50 + s_img2.shape[1],topmost[1] -40 + s_img2.shape[0]), (0,0,0), -1)
					#cv2.rectangle(frame, (topmost[1] -40 ,topmost[0] -50), (topmost[1]-40 + s_img2.shape[0],topmost[0] -50 + s_img2.shape[1]), (255,0,0), -1)

			
			#cv2.imshow('thresh', thresh2)

			return frame,draw,command,topmost,whiteboard, thresh2
    			#cv2.imshow('gesture_window', frame)

if __name__ == "__main__":
		gesture_track = GestureTracker()
		gesture_track.run()
